package com.runa.monitor.platinterface.netservice.handler;

import com.runa.monitor.platinterface.base.BaseContainer;
import com.runa.persistence.util.SpringContextUtil;
import com.runa.monitor.platinterface.netservice.equipment.NetEqu;
import com.runa.monitor.platinterface.netservice.equipment.furuisi.FuRuiSiClientDriver;
import com.runa.monitor.platinterface.platService.AfterOnlineService;
import com.runa.monitor.platinterface.platService.NetEquService;
import com.runa.persistence.util.LogUtil;
import com.runa.protocol.dto.DtuReport;
import com.runa.rccprotocol.dto.ConcentratorElectric;
import com.runa.rccprotocol.dto.furuisi.FuRuiSiReportAck;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.nio.NioDatagramChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author zhuj
 */
@ChannelHandler.Sharable
public class RccReportHandler extends SimpleChannelInboundHandler<DtuReport> {

    private static final Logger logger = LoggerFactory.getLogger(RccReportHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DtuReport msg) {
        NetEquService netEquService = SpringContextUtil.getBean(NetEquService.class);
        AfterOnlineService afterOnlineService = SpringContextUtil.getBean(AfterOnlineService.class);
        NetEqu<String> netEqu = netEquService.getNetEquBySerial(msg.getData());
        if (netEqu != null) {
            if (msg.isMustAck()) {
                ctx.channel().writeAndFlush(msg.getAck());
                LogUtil.info(msg.getData(), msg.getAck().getData(), "响应");
            }
            if (msg.getClass().getName().contains("Report")) {
                netEqu.heartbeatUpdate();
                if (NetEqu.getSerial(ctx.channel().id().asLongText()) == null) {
                    netEqu.register(ctx.channel());
                    BaseContainer.netStatusCallback().rccStatusChange(msg.getData(), true);
                    logger.info("计量客户端Report: {} 已连接注册. {}", msg.getData(), ctx.channel().remoteAddress());
                    afterOnlineService.trigger(msg.getData ());
                } else {
                    BaseContainer.netStatusCallback().rccStatusChange(msg.getData(), true);
                    logger.info("计量客户端Report: {} 发送心跳.", msg.getData());
                }
            }
            if (msg.getClass().getName().contains("Register")) {
                netEqu.heartbeatUpdate();
                netEqu.register(ctx.channel());
                BaseContainer.netStatusCallback().rccStatusChange(msg.getData(), true);
                logger.info("计量客户端Register: {} 已连接注册. {}", msg.getData(), ctx.channel().remoteAddress());
                afterOnlineService.trigger(msg.getData());
            } else if (msg.getClass().getName().contains("Heart")) {
                netEqu.heartbeatUpdate();
                if (!netEqu.online()){
                    netEqu.register(ctx.channel());
                    logger.info("计量客户端Heart: {} 通过心跳注册.", msg.getData());
                }
                BaseContainer.netStatusCallback().rccStatusChange(msg.getData(), true);
                logger.info("计量客户端Heart: {} 发送心跳.", msg.getData());
            } else if (msg.getClass().getName().contains("Electric")) {
                netEqu.heartbeatUpdate();
                BaseContainer.netStatusCallback().rccNetEquReport(msg.getData(), ((ConcentratorElectric)msg).getReportData());
                logger.info("计量客户端: {} 上报采集器参数.", msg.getData());
            }
        } else if (msg.isMustAck() && msg.getAck() instanceof FuRuiSiReportAck) {
            LogUtil.getLogAndInfo(FuRuiSiClientDriver.FRS_NAME, "弗瑞斯", ctx.channel().id().asLongText());
            ctx.channel().writeAndFlush(msg.getAck());
            LogUtil.info("furuisi", msg.getAck().getData(), "响应");
        } else {
            logger.debug("非法客户端: {} 尝试连接.", msg.getData());
            if (!(ctx.channel() instanceof NioDatagramChannel)) {
                ctx.channel().close().addListener(future -> {
                    if (future.isSuccess()) {
                        logger.debug("关闭非法客户端连接：{} 成功", msg.getData());
                    } else {
                        logger.debug("关闭非法客户端连接：{} 失败", msg.getData());
                    }
                });
            }
        }
    }

}
